﻿namespace BattleShip
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    public class Playground
    {
        private StatmentOfPositionInMatrix[,] matrix;
        private List<int> matrixElements;

        public Playground()
        {
            matrix = new StatmentOfPositionInMatrix[10, 10];
            matrixElements = new List<int>();

            for (int i = 0; i < 100; i++)
            {
                matrixElements.Add(i);
            }
        }

        public void ChangeMatrixStatment(string[] positions, StatmentOfPositionInMatrix possitionStatment)
        {
            if (positions.Length <= 0)
            {
                throw new ArgumentException("Array with positions is empty!");
            }

            if (possitionStatment == StatmentOfPositionInMatrix.Empty)
            {
                string[] coordinatesArr = positions[0].Split(' ');
                int xCoordinate = int.Parse(coordinatesArr[0]);
                int yCoordinate = int.Parse(coordinatesArr[1]);
                matrix[xCoordinate, yCoordinate] = StatmentOfPositionInMatrix.Empty;
                RemoveUsedElementsFromList(xCoordinate, yCoordinate);
            }
            else if (possitionStatment == StatmentOfPositionInMatrix.Hitted)
            {
                string[] coordinatesArr = positions[0].Split(' ');
                int xCoordinate = int.Parse(coordinatesArr[0]);
                int yCoordinate = int.Parse(coordinatesArr[1]);
                matrix[xCoordinate, yCoordinate] = StatmentOfPositionInMatrix.Hitted;
                RemoveUsedElementsFromList(xCoordinate, yCoordinate);
            }
            else if (possitionStatment == StatmentOfPositionInMatrix.Destroyed)
            {
                foreach (var position in positions)
                {
                    ChangeDestroyedPossitionAndTheNeighborhood(position);
                }
            }
        }

        public int GetCountOfMatrixElelemnts()
        {
            return matrixElements.Count();
        }

        public int GetElementForAttack(int index)
        {
            if (index < 0 || index >= matrixElements.Count)
            {
                throw new IndexOutOfRangeException("Index does not exist in available positions!");
            }

            int numberFromIndexPossition = matrixElements[index];
            matrixElements.RemoveAt(index);
            return numberFromIndexPossition;
        }

        public StatmentOfPositionInMatrix[,] GetMatrixWithElements()
        {
            return matrix;
        }

        public bool IsPositionVisited(string coordinates)
        {
            string[] coordinatesArr = coordinates.Split(' ');
            int xCoordinate = int.Parse(coordinatesArr[0]);
            int yCoordinate = int.Parse(coordinatesArr[1]);
            if (matrix[xCoordinate, yCoordinate] == StatmentOfPositionInMatrix.NotChecked)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        private void ChangeDestroyedPossitionAndTheNeighborhood(string coordinate)
        {
            string[] coordinatesArr = coordinate.Split(' ');
            int xCoordinate = int.Parse(coordinatesArr[0]);
            int yCoordinate = int.Parse(coordinatesArr[1]);
            matrix[xCoordinate, yCoordinate] = StatmentOfPositionInMatrix.Destroyed;
            RemoveUsedElementsFromList(xCoordinate, yCoordinate);

            // UpLeft -1, -1
            if (MatrixFunctions.IsPositionInTheMatrix(xCoordinate - 1, yCoordinate - 1))
            {
                matrix[xCoordinate - 1, yCoordinate - 1] = StatmentOfPositionInMatrix.Destroyed;
                RemoveUsedElementsFromList(xCoordinate - 1, yCoordinate - 1);
            }

            // UpMid -1, 0
            if (MatrixFunctions.IsPositionInTheMatrix(xCoordinate - 1, yCoordinate))
            {
                matrix[xCoordinate - 1, yCoordinate] = StatmentOfPositionInMatrix.Destroyed;
                RemoveUsedElementsFromList(xCoordinate - 1, yCoordinate);
            }

            // UpRight -1, +1
            if (MatrixFunctions.IsPositionInTheMatrix(xCoordinate - 1, yCoordinate + 1))
            {
                matrix[xCoordinate - 1, yCoordinate + 1] = StatmentOfPositionInMatrix.Destroyed;
                RemoveUsedElementsFromList(xCoordinate - 1, yCoordinate + 1);
            }

            // MidLeft 0, -1
            if (MatrixFunctions.IsPositionInTheMatrix(xCoordinate, yCoordinate - 1))
            {
                matrix[xCoordinate, yCoordinate - 1] = StatmentOfPositionInMatrix.Destroyed;
                RemoveUsedElementsFromList(xCoordinate, yCoordinate - 1);
            }

            // MidRight 0, +1
            if (MatrixFunctions.IsPositionInTheMatrix(xCoordinate, yCoordinate + 1))
            {
                matrix[xCoordinate, yCoordinate + 1] = StatmentOfPositionInMatrix.Destroyed;
                RemoveUsedElementsFromList(xCoordinate, yCoordinate + 1);
            }

            // DownLeft +1 , -1
            if (MatrixFunctions.IsPositionInTheMatrix(xCoordinate + 1, yCoordinate - 1))
            {
                matrix[xCoordinate + 1, yCoordinate - 1] = StatmentOfPositionInMatrix.Destroyed;
                RemoveUsedElementsFromList(xCoordinate + 1, yCoordinate - 1);
            }

            // DownMid +1, 0
            if (MatrixFunctions.IsPositionInTheMatrix(xCoordinate + 1, yCoordinate))
            {
                matrix[xCoordinate + 1, yCoordinate] = StatmentOfPositionInMatrix.Destroyed;
                RemoveUsedElementsFromList(xCoordinate + 1, yCoordinate);
            }

            // DownRight +1, +1
            if (MatrixFunctions.IsPositionInTheMatrix(xCoordinate + 1, yCoordinate + 1))
            {
                matrix[xCoordinate + 1, yCoordinate + 1] = StatmentOfPositionInMatrix.Destroyed;
                RemoveUsedElementsFromList(xCoordinate + 1, yCoordinate + 1);
            }
        }

        private void RemoveUsedElementsFromList(int xCoordinate, int yCoordinate)
        {
            string numberAsStr = xCoordinate.ToString() + yCoordinate.ToString();
            int coordinateNumber = int.Parse(numberAsStr);
            int position = matrixElements.BinarySearch(coordinateNumber);
            if (position < 0)
            {
                return;
            }

            matrixElements.RemoveAt(position);
        }
    }
}
